package com.cims.bpm.security.utils.sm2;

import java.math.BigInteger;

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.math.ec.ECPoint;

public class Sm2BasicAgreement {

	protected ECPrivateKeyParameters privKey;

	public void init(CipherParameters parameters) {
		if (parameters instanceof ParametersWithRandom) {
			parameters = ((ParametersWithRandom) parameters).getParameters();
		}
		this.privKey = (ECPrivateKeyParameters) parameters;
	}

	public int getFieldSize() {
		return (privKey.getParameters().getCurve().getFieldSize() + 7) / 8;
	}

	public BigInteger[] calculateAgreement(CipherParameters pubKey) throws Exception {
		ECPublicKeyParameters pub = (ECPublicKeyParameters) pubKey;
		if (!pub.getParameters().equals(privKey.getParameters())) {
			throw new Exception("ECDH public key has wrong domain parameters");
		}

		ECPoint P = pub.getQ().multiply(privKey.getD()).normalize();
		if (P.isInfinity()) {
			throw new Exception("Infinity is not a valid agreement value for ECDH");
		}
		return new BigInteger[] { P.getAffineXCoord().toBigInteger(), P.getAffineYCoord().toBigInteger() };
	}
}
